package service

import (
	"fmt"
	"log"

	kadefine "kiwi/actor/define"
)

type IService interface {
	Start(ctx kadefine.Context, args ...any) error
	Stop()
}

type Producer func(args ...any) IService

type factory struct {
	name     string
	producer Producer
}

func createFactory(name string, producer Producer) *factory {
	return &factory{
		name:     name,
		producer: producer,
	}
}

var m = createFactoryManager()

type factoryManager struct {
	factories map[string]*factory
}

func createFactoryManager() *factoryManager {
	m := &factoryManager{
		factories: map[string]*factory{},
	}
	return m
}

func Register(name string, producer Producer) {
	m.register(name, producer)
}

func (m *factoryManager) register(name string, producer Producer) {
	if producer == nil {
		log.Panicf("register service factory fail, producer = nil, name=[%v]", name)
	}

	if f, ok := m.factories[name]; ok {
		log.Panicf("duplicate service factory, id=[%v], factory=[%+v]", name, f)
	}

	m.factories[name] = createFactory(name, producer)
}

func Produce(name string, args ...any) (IService, error) {
	return m.produce(name, args...)
}

func (m *factoryManager) produce(name string, args ...any) (IService, error) {
	if factory := m.factories[name]; factory != nil {
		return factory.producer(args...), nil
	}
	return nil, fmt.Errorf("unsupported service, name=[%s]", name)
}
